/**
 * @author phuang5
 * 
 * require language/{xx}_us/qs_quote_{xx}_us.js
 * require quote_settingpanel.js
 * require autoCompleteBox.js
 * require quote_datapoints_map.js
 * require quotebase.js
 * 
 */
if (!QSAPI) {
	var QSAPI = {
		Widget : {}
	};
} else if (!QSAPI.Widget) {
	QSAPI.Widget = {};
}

QSAPI.Widget.Quote = function(container, option, callback, id) {
	var t=QS_Lang.quote;
	option = option || {};
	callback = callback || {};
	this.container = $(container);
	this.id = id || 'quote_id_' + Util.IdProducer.getId();
	this.subContainerStr = {
		header : '<div class="qs-r qutoe_hd qs-api-headbar"></div>',
		qs : '<div id="quote_container"></div>'
	};
	this.gKey = null;
	this.ticker = null;
	this.lastGKey = null;
	this.dataPointsPool=[];

	this.option = {
		quoteToolBar : {
			position : 'top',
			queryBox : {
				show : true,
				buttonText : t.go,
			},
			setting : {
				show : true,
				buttonText : t.settings,
				width : 150,
				height : 200
			}
		},
		width : 400,
		height : 400,
		dataPoints:[]
	};	
	this.option.id=this.id;
	this.tickerObject=null;
	this.callback = $.extend(true, {}, callback);
	this.sequence=[];
	this.sequenceMap={};
	this.removeSequenceMap={};
	this.option = $.extend(true, this.option, option);
	this.el=$('<div id="'+this.id+'"></div>').appendTo(this.container);
};

QSAPI.Widget.Quote.prototype = {
	init : function(option) {		
		this.settingData=this.__buildSettingItems();
		$.extend(true, this.option , option);
	},
	acceptTicker : function(tickerObject) {
		var self=this;
		if (tickerObject.valid){
			var d;
			self.lastGKey=self.gKey;
			self.gKey=tickerObject.gkey;
	        d = gData[self.gKey] ? gData[self.gKey] : gData[gIdMap[self.gKey]];	 
	        var ticker=d['performanceId']||d['secId'];
	        if (self.gKey==self.lastGKey){
	        	self.__executeCallback('afterAcceptTicker');
	        	return;
	        }
		}else{
			this.__executeCallback('afterAcceptTicker');
			return;
		}
		QSAPI.DataManager.getStaticData([tickerObject],function(){			
		self.ticker=ticker;
        if(self.option.showTitle){
        	self.setTitle('Quote:',tickerObject.symbol);
        }
		
		var dm=QSAPI.DataManager;
		var unSubscribeCallballs={
    			onSuccess:function(){
    				self.__unSubscribeEvent();
    			},
    			onFailure:function(){;}
		};
		var subscribeCallballs={
    			onSuccess:function(){
    				self.__subscribeEvent();
    			},
    			onFailure:function(){;}				
		};
		if (self.tickerObject){
			self.lastTickerObject=self.tickerObject;
		}
		self.tickerObject=tickerObject;
		
		if (self.quoteWidget){
			self.donotAddDataPoint=true;
		}
		
		if (!self.donotAddDataPoint) {
			if (self.option.dataPoints) {
				self.addDataPoints(self.option.dataPoints);
			}
			self.__createQuoteWidget(tickerObject.mType);
		} 
		self.quoteWidget.setParent(self);
		self.quoteWidget.setGKey(tickerObject.getField('gkey'));
		//connect data
		self.dataComponent = {
			subscribeID : 'qs_quote_data_' + self.id,
			updateData : function(tickerObject, data) {
				self.__updateData(tickerObject.gkey, data);
				//console.log("Update:"+data);
			}
		};		
	    if (dm._getType() == dm.TYPE.PUSH) {
	    	if (self.lastGKey) {
	    		dm.unSubscribePush(self.dataComponent, [self.lastTickerObject],unSubscribeCallballs);	    		
	    	}
	    	dm.subscribePush(self.dataComponent, [tickerObject],subscribeCallballs);
		} else if (dm._getType() == dm.TYPE.PULL) {
			if (self.lastGKey) {
				dm.unSubscribePull(self.dataComponent, [self.lastTickerObject],unSubscribeCallballs);
			}
			dm.subscribePull(self.dataComponent, [tickerObject],subscribeCallballs);
		}

		//load widget
	    if (!self.donotAddDataPoint){
	    	self.__executeAddDataPoints();
	    	self.__execRemoveDataPoints();
	    }
		
		var t=QS_Lang.quote;
		
		self.changeOutSize(self.option.width,self.option.height,true);

		var quoteWidget = self.quoteWidget;
		quoteWidget.changeUniqueLastText(tickerObject.mType == 'FO' ? t.lastnav
							: t.lastprice);		
		quoteWidget.changeHeadInfo({
						companyName : tickerObject.Name || "",
						symbol : (tickerObject.msexch || "") +(tickerObject.msexch?":":"")+(tickerObject.clientTicker	|| tickerObject.ticker || ""),
						secType : tickerObject.mType || ""
					});
		self.__executeCallback('afterAcceptTicker');
		});		
	},
    __createQuoteWidget:function(sType){
    		var option=$.extend(true,{},this.option);
    		var quote=this.quoteWidget=$.extend(true,{},QSAPI.BaseQuote,{sequence:this.settingSequence}); //new quotewidget
    		quote.container=$(this.subContainerStr.qs).appendTo(this.el);
    		quote.callback=$.extend(true, {}, this.callback);
    		quote.option=$.extend(true,quote.option,quote.defaultConfig,this.option);
    		quote.template = this.option.template;
    		quote.secType=sType;
    		quote.__buildDatapoints=this.__buildDatapoints;
    		quote.init();
    		
    		if (option.quoteToolBar.setting.show || option.quoteToolBar.queryBox.show){
    			var top=option.quoteToolBar.position=='top';
    			var bar=null;
    			if (top){
    				bar=this.headerbar=$(this.subContainerStr.header).insertBefore(quote.container);
    			}else{
    				bar=this.headerbar=$(this.subContainerStr.header).insertAfter(quote.container);
    			}
    			this.__optionQueryBox(bar, option);
    			this.__optionSetting(bar,option);
    			var quote_setting=this.quote_setting;
			    quote.callback = $.extend(true, quote.callback, {
				onRemoveRow : function(id, row) {
					if (quote_setting != null) {
						quote_setting.selectDataPointChk([ id ], false);
						quote_setting.selectAllChkBtn(false);
					}
				}				
			});
    		}

    },	
	changeOutSize : function(w, h,flag) {
        if(w>0&&w!=this.option.width){
            this.option.width=w;
        }
        if(h>0&&h!=this.option.height){
            this.option.height=h;
        }
        this.quoteWidget.changeOutSize(w,h,flag);
        if(this.headerbar){
        	this.headerbar.width(this.option.width);
        }
	},
	addDataPoints : function(dataPoints) {
		var dataPointsObjList=[];
		if (dataPoints){
			var sequence=this.__getUniqueSequence(dataPoints);
			dataPointsObjList=this.__buildDatapoints(this.gKey,sequence);		
			this.dataPointsPool=this.dataPointsPool.concat(dataPointsObjList);	
		}
		if (this.quoteWidget){
			this.__executeAddDataPoints(dataPointsObjList);
			//console.log("this.__executeAddDataPoints(dataPointsObjList)");
			this.dataPointsPool=[];
		}
		if (typeof(arguments[1]) != 'undefined' && arguments[1]=='noCB'){
		}else{
			this.__executeCallback('afterAddDatapoints');
		}
	},
	__addDataPointBySetting:function(dataPointVal){
		if (this.dataPointsPool){
			for (var i=0,l=this.dataPointsPool.length;i<l;i++){
				if (this.dataPointsPool[i].val==dataPointVal){
					return;
				}
			}
			//console.log("Add:"+dataPointVal+ '  this.dataPoints.length='+this.dataPointsPool.length );
			this.dataPointsPool=this.dataPointsPool.concat(this.__buildDatapoints(this.gKey,[dataPointVal]));
			this.sequenceMap[dataPointVal]=dataPointVal;
		}
	},
	__removeDataPointBySetting:function(dataPointVal){
		if (this.dataPoints && this.dataPoints.length>0){
			//console.log("Remove: "+dataPointVal + '  this.dataPoints.length='+this.dataPointsPool.length);
	   		 for(var j=0;j<this.dataPoints.length;j++){
	   			 if (dataPoints[i].val==dataPointVal){
	   				 this.removeSequenceMap[dataPointVal]=dataPointVal;
	   				 this.dataPoints.splice(j,1);
	   				 break;
	   			 }
	   		 }
		}
	},
	__executeAddDataPoints:function(dataPointsObjList){
		var quoteWidget=this.quoteWidget;
		if (dataPointsObjList){
			quoteWidget.addDataPoints(dataPointsObjList);
		}else{
			quoteWidget.addDataPoints(this.dataPointsPool);
		}
        if (quoteWidget.dataPoints.length>0 && this.quote_setting){
            this.quote_setting.rebindData(quoteWidget.dataPoints,this.settingSequence);            
        }
	},
	__buildSettingItems:function(){
		this.settingSequence=[];
		var s=[];
		for (dp in QSAPI.DatapointMap){
			this.settingSequence.push(dp);
			s.push(QSAPI.DatapointMap[dp]);
		}
		return s;
	},
	removeDataPoints : function(dataPoints) {
		var dataPointsObjList=[];
		var IS_REMOVE=true;
		if (!this.removeDatapointsPool) {
			this.removeDatapointsPool = [];
		}		
		if (dataPoints){
			var sequence=this.__getUniqueSequence(dataPoints,IS_REMOVE);
			dataPointsObjList=this.__buildDatapoints(this.gKey,sequence);		
			this.removeDatapointsPool=this.removeDatapointsPool.concat(dataPointsObjList);	
		}
		if (this.quoteWidget){
			this.__execRemoveDataPoints(dataPointsObjList);
		}
		this.__executeCallback('afterRemoveDatapoints');
	},
	__execRemoveDataPoints: function(dataPointsObjectList){
		var quoteWidget=this.quoteWidget;
		if (dataPointsObjectList){
			quoteWidget.removeDataPoints(dataPointsObjectList);
	    	for (var i = 0, l = dataPointsObjectList.length; i < l ; i++) {
	    		 for(var j=0;j<this.dataPointsPool.length;j++){
	    			 if (dataPointsObjectList[i].val==this.dataPointsPool[j].val){
	    				 this.dataPointsPool.splice(j,1);	    				 
	    				 break;
	    			 }
	    		 }
	    		 for(var j=0;j<this.removeDatapointsPool.length;j++){
	    			 if (dataPointsObjectList[i].val==this.removeDatapointsPool[j].val){
	    				 this.removeDatapointsPool.splice(j,1);	    				 
	    				 break;
	    			 }
	    		 }
	    	}			
		}else{
			quoteWidget.removeDataPoints(this.removeDatapointsPool);
	    	if (this.removeDatapointsPool){
				for (var i = 0, l = this.removeDatapointsPool.length; i < l ; i++) {
		    		 for(var j=0;j<this.dataPointsPool.length;j++){
		    			 if (this.removeDatapointsPool[i].val==this.dataPointsPool[j].val){
		    				 this.dataPointsPool.splice(j,1);
		    				 delete this.removeDatapointsPool[i];
		    				 break;
		    			 }
		    		 }
		    	}
	    	}
		}
        if (quoteWidget.dataPoints.length>0 && this.quote_setting){
            this.quote_setting.rebindData(quoteWidget.dataPoints,this.settingSequence);            
        }		
	},
	setTitle:function(title){
		this.title=title;
	},
	clear : function() {
		   this.__executeCallback('beforeClear');
	       this.__emptyQuoteWidget();
	       for(var p in this){
	            if(!p || p == 'clear'){continue;}
	            this[p] = null;
	            delete this[p];
	       }
	},
    __emptyQuoteWidget:function(){
    	if (this.quoteQueryBox){
    		this.quoteQueryBox.clear();
    		delete this.quoteQueryBox;
    	}
    	if (this.quote_setting){
    		this.quote_setting.clear();
    		delete this.quote_setting;
    		delete this.quoteSetting;
    	}
    	if (this.quoteWidget){
    		this.quoteWidget.clear();
    		delete this.quoteWidget;
    	}
        this.container[0].innerHTML='';
    },
    __updateData:function(gKey,data){
    	if ( this.quoteWidget){
    		this.quoteWidget.forceUpdateUnqiueData();
    		this.quoteWidget.updateData(this.quoteWidget.dpfMap)
    	}
    },
    __unSubscribeEvent:function(){
    	if (this.lastTickerObject){
    		this.lastTickerObject.clear();
    		this.lastTickerObject=null;
    	}
    },
    __subscribeEvent:function(){
    },
    __buildDatapoints:function(gKey,sequence){
    	var dp=[];
    	var o;
    	for (var i=0;i<sequence.length;i++){
    		o=QSAPI.DatapointMap[sequence[i]];  
    		o=$.extend({data:QS_Formatter(gKey,[o.val],o.dataType)},o);
    		dp.push(o);
    	}
    	return dp;
    },
    __reBuildDatapoints:function(gKey,dataPoints){
    	for (var i=0;i<dataPoints.length;i++){
    		o=QSAPI.DatapointMap[dataPoints[i].val];  
    		$.extend({data:QS_Formatter(gKey,[o.val],o.dataType)},o);
    	}
    },
	__adjustSettingPanelPosition:function(anacliticObject,settingObject){
		var so=$(settingObject);
		var left,top;
		if (anacliticObject.offset().left+anacliticObject.outerWidth()-so.outerWidth()>0){
			left=anacliticObject.offset().left+anacliticObject.outerWidth()-so.outerWidth();
		}else{
			left=anacliticObject.left;
		}
//		if (anacliticObject.offset().top+anacliticObject.outerHeight()+so.outerHeight()<$('body').innerHeight()){
			top=anacliticObject.offset().top+anacliticObject.outerHeight();
//		}else{
//			top=anacliticObject.offset().top-so.outerHeight();
//		}
		so.css({'top':top,'left':left,'z-Index':10000});
	},

	__getUniqueSequence:function(sequence,isRemove){
		if (!sequence) return null;
		if (!$.isArray(sequence)){
			sequence=sequence.split(",");			
		}
		var s=[];
		for(var i=0,l=sequence.length;i<l;i++){
			if(sequence[i]=='LowPrice,HighPrice'){
				s.push('HighPrice');
				s.push('LowPrice');
			}else if(sequence[i]=='st169,st168'){
				s.push('st168');
                s.push('st169');
			}else{
				s.push(sequence[i]);
			}
		}
		var result=[];
			for (var i=0,l=s.length;i<l;i++){
				if (isRemove){
					if (!this.removeSequenceMap[s[i]]){
						result.push(s[i]);
						this.removeSequenceMap[s[i]]=s[i];
					}					
				}else{
					if (!this.sequenceMap[s[i]]){
						result.push(s[i]);
						this.sequenceMap[s[i]]=s[i];
					}
				}
			}
		return result;
	},	
    __executeCallback:function(event,data){
    	if (typeof this.callback[event]=='function'){
    		this.callback[event](data);    		
    	}
    },
    __optionSetting:function(container,option){
		if (option.quoteToolBar.setting.show){
			var quoteSetting=this.quoteSetting=$('<a href="javascript:void(0)" class="qs-ui-btn setting quote-setting">'+option.quoteToolBar.setting.buttonText+'</a>').appendTo(container);
			var id='qs_setting_'+option.id;
			var self=this,quote=this.quoteWidget;
			var settingPanel=this.settingPanel=new QSAPI.SettingPanelContianer(container);
            var quote_setting=this.quote_setting=new QSAPI.QuoteSettingPanel(settingPanel.getDom(),{
                onClick:function(val,isSelected){
                    if(isSelected){
                    	if (self.sequenceMap){
                    		delete self.sequenceMap[val];
                    	}
                    	self.addDataPoints([val]);
                    }else{
                    	if (self.removeSequenceMap){
                    		delete self.removeSequenceMap[val];
                    	}
                    	self.removeDataPoints([val]);                    	
                    }
                    self.changeOutSize(self.option.width,self.option.height,true);
                    self.__executeCallback('onStateChange');
                },
                onClickAll:function(isSelected){
                    if(isSelected){
                        quote.addAllDataPoints();
                    }else{
                        quote.removeAllDataPoints();
                    }
                    self.__executeCallback('onStateChange');                    
                }
            }); 
            quote_setting.init(this.settingData); 
            var adjPos=this.__adjustSettingPanelPosition;
            container.find('.quote-setting').click(function(e){
                settingPanel.toggle();
                if(settingPanel.getVisible()){
                	self.__resizeSettingPanel();
                	adjPos(quoteSetting, settingPanel.el);
                }
            }); 
		}      	
    },
    __resizeSettingPanel:function(){
    	var setting=this.option.quoteToolBar.setting;
    	this.settingPanel.resize(setting.width+14,setting.height+78,true);    	
    	this.quote_setting.resize(setting.width,setting.height,true);    	
    },
    __optionQueryBox:function(container,option){
		if (option.quoteToolBar.queryBox.show){
			var id='autocomplete_'+option.id;
			var self=this;
			this.quoteQueryBox=$('<input id="'+id+'"  type="text" value="" class="qs-ui-ipt sdk-autocomplete-input"/><a href="javascript:void(0)" class="qs-ui-btn quote-btn go">'+option.quoteToolBar.queryBox.buttonText+'</a>').appendTo(container);
    		var acb=new QSAPI.Widget.AutoComplete(this.container,
    				{category : ["Equities","Option"]},{
    			onClick:function(ticker){
    				if (self.settingPanel){self.settingPanel.hide()};
    				self.acceptTicker(ticker);
    			}    			
    		},id);
    		acb.subscribe(id);
    		$(container).find(".go").bind("click",function(e){
    			acb.trigger(id);
    		});
		}   	
    }
};